package com.engr.springbooteasypoi.thread;

import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author : liuYanXin
 * @Description : 锁
 * @Date : 2020-03-27
 */
public class LockCls {

    public static void main(String[] args) {

        MyCount myCount = new MyCount("A", 500);
        Lock lock = new ReentrantLock();
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 10,
                10L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        User u1 = new User("A1", myCount, -100, lock);
        User u2 = new User("A2", myCount, -100, lock);
        User u3 = new User("A3", myCount, -50, lock);
        User u4 = new User("A4", myCount, +20, lock);
        for (int i = 0; i < 10; i++) {
            poolExecutor.submit(u1);
            poolExecutor.submit(u2);
            poolExecutor.submit(u3);
            poolExecutor.submit(u4);
        }

        poolExecutor.shutdown();

    }
}

/**
 * 信用卡的用户
 */
class User implements Callable {

    private String name;
    private MyCount myCount;
    private int iocash;
    private Lock lock;


    public User(String name, MyCount myCount, int iocash, Lock lock) {
        this.name = name;
        this.myCount = myCount;
        this.iocash = iocash;
        this.lock = lock;
    }

    @Override
    public Object call() throws Exception {
        // 获取锁
        lock.lock();
        try {
            // 执行现金任务
            System.out.println(Thread.currentThread().getName() + "->" + name + " 正在操作：" + myCount + "账户,金额为：" + iocash + ",当前金额为：" + myCount.getCash());
            myCount.setCash(myCount.getCash() + iocash);
            System.out.println(Thread.currentThread().getName() + "->" + name + " 正在操作：" + myCount + "账户,金额为：" + iocash + ",当前金额为：" + myCount.getCash());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return myCount.getCash();
    }
}

/**
 * 信用卡账户
 */
class MyCount {

    private String oid;

    private int cash;

    public MyCount(String oid, int cash) {
        this.oid = oid;
        this.cash = cash;
    }

    public String getOid() {
        return oid;
    }

    public void setOid(String oid) {
        this.oid = oid;
    }

    public int getCash() {
        return cash;
    }

    public void setCash(int cash) {
        this.cash = cash;
    }

    @Override
    public String toString() {
        return "MyCount{" +
                "oid='" + oid + '\'' +
                ", cash=" + cash +
                '}';
    }
}